1、题干
给定一个整数数组 nums
和一个整数 k
,请返回其中出现频率前 k
高的元素。可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
提示:
1 <= nums.length <= 105
k
的取值范围是[1, 数组中不相同的元素的个数]
- 题目数据保证答案唯一,换句话说,数组中前
k
个高频元素的集合是唯一的
进阶:所设计算法的时间复杂度 必须 优于 O(n log n)
,其中 n
是数组大小。
注意:本题与主站 347 题相同:https://leetcode-cn.com/problems/top-k-frequent-elements/
2、解法1-API排序
先使用哈希映射 map
对所有整数进行计数,然后将 map
中的键值对存入数组并使用排序API按数量降序排序,最后返回前 k
个数字
3、代码
var topKFrequent = function (nums, k) {
const map = new Map();
for (const n of nums) map.set(n, 1 + (map.get(n) || 0));
const arr = [];
for (const kv of map) arr.push(kv);
return arr.sort((a, b) => b[1] - a[1]).slice(0, k).map(a => a[0]);
};
4、复杂度
- 时间复杂度:
- 空间复杂度:
5、解法2-桶排序
先使用哈希映射 map
对所有整数进行计数,然后将 map
中的键值对存入按数量存入桶中,最后返回前 k
个数字。其时间复杂度为 ,解决了进阶问题。
6、代码
var topKFrequent = function (nums, k) {
const map = new Map();
for (const n of nums) map.set(n, 1 + (map.get(n) || 0));
const buckets = new Array(nums.length + 1);
for (const [n, v] of map) !buckets[v] ? buckets[v] = [n] : buckets[v].push(n);
const res = [];
for (let i = buckets.length - 1; i > -1; i--) {
if (res.length >= k) break;
if (buckets[i]) res.push(...buckets[i]);
}
return res.length > k ? res.slice(0, k) : res;
};
7、复杂度
- 时间复杂度:
- 空间复杂度: